package com.xteam.xnetworkdisk.utils;

import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.model.GeneratePresignedUrlRequest;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import com.xteam.xnetworkdisk.utilsinterface.FileUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.Objects;

@Component
public class OssUtil implements FileUtils {

    private static final String OSS_ACCESS_KEY_ID = "LTAI5tFhWMnjMBiRWzoa6Khy";
    private static final String OSS_ACCESS_KEY_SECRET = "4ldn1bUINOVhsjRGDHgppKTks5np8b";
    private static final String bucketName = "smart-medicine-box";
    private static final String endpoint = "oss-cn-beijing.aliyuncs.com";

    public String uploadFile(MultipartFile file, String bucketName) throws Exception {
        try (InputStream fileInputStream = file.getInputStream()) {
            return upload(fileInputStream, file.getOriginalFilename());
        }
    }

    public void createBucket(String bucketName) {

    }

    @Override
    public String copyFile(String bucketName, String oldFileName) {
        return "";
    }

    @Override
    public String uploadFile(MultipartFile file, String bucketName, String suffix) {
        return "";
    }

    @Override
    public String uploadFile(InputStream file, String bucketName, String suffix, Long fileSize, String contentType) {
        return "";
    }

    @Override
    public boolean deleteFile(String fullPath) {
        // OSS SDK does not provide a direct way to delete a file by URL, so this is not implemented.
        // You would need to parse the bucket name and file name from the fullPath and then call the delete method.
        return false;
    }

    @Override
    public String[] parseBucketAndFilename(String fullPath) {
        // OSS full path parsing logic here
        // Example: "https://bucket-name.oss-cn-beijing.aliyuncs.com/file-name"
        String[] parts = fullPath.split("/", 2);
        if (parts.length < 2) {
            return new String[]{null, null};
        }
        String bucketName = parts[0].split("\\.")[0];
        String filename = parts[1];
        return new String[]{bucketName, filename};
    }

    @Override
    public String uploadFile(InputStream inputStream, String bucketName, String fileName, String contentType) throws Exception {
        return upload(inputStream, fileName);
    }

    @Override
    public String generatePresignedUrl(String fullPath, String filenameR) {
        return "";
    }

    @Override
    public InputStream getFileInputStreamFromDisplayPath(String displayPath) {
        return null;
    }

    private String upload(InputStream fileInputStream, String fileName) {
        String fileUrl = null;
        OSS ossClient = new OSSClientBuilder().build(endpoint, OSS_ACCESS_KEY_ID, OSS_ACCESS_KEY_SECRET);

        try {
            String format = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
            String dir = format + "/";
            String objectName = dir + fileName;

            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, fileInputStream);
            PutObjectResult result = ossClient.putObject(putObjectRequest);

            fileUrl = getURL(objectName);
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }

        return fileUrl != null ? fileUrl : "文件路径出现错误";
    }

    private String getURL(String fileName) {
        OSS oss = new OSSClientBuilder().build(endpoint, OSS_ACCESS_KEY_ID, OSS_ACCESS_KEY_SECRET);
        try {
            LocalDateTime time = LocalDateTime.now().plusDays(100);
            Date expiration = Date.from(time.atZone(ZoneId.systemDefault()).toInstant());
            URL url = oss.generatePresignedUrl(bucketName, fileName, expiration);
            return url.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            oss.shutdown();
        }
    }

    /**
     * 生成新的预签名 URL
     *
     * @param fileName 文件名
     * @return 新的预签名 URL
     */
    public String getNewPresignedUrl(String fileName) {
        OSS ossClient = new OSSClientBuilder().build(endpoint, OSS_ACCESS_KEY_ID, OSS_ACCESS_KEY_SECRET);
        try {
            // 设置过期时间为当前时间后的1小时（或根据需要调整）
            Date expiration = new Date(System.currentTimeMillis() + 60 * 60 * 1000); // 1小时
            GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, fileName, HttpMethod.GET);
            request.setExpiration(expiration);
            URL url = ossClient.generatePresignedUrl(request);
            return url.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            ossClient.shutdown();
        }
    }

}
